package cn.com.twoke.app.pin_dou_dou.core;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 更新下载器
 * 用于下载更新包
 */
@Slf4j
public class UpdateDownloader {

    /**
     * 下载更新包
     *
     * @param downloadUrl 下载URL
     * @param parent      父窗口，用于显示进度对话框
     * @param callback    下载完成后的回调
     */
    public static void downloadUpdate(String downloadUrl, JFrame parent, DownloadCallback callback) {
        // 在后台线程中执行下载
        new Thread(() -> {
            RandomAccessFile raf = null;
            InputStream in = null;
            try {
                // 获取用户主目录下的Downloads文件夹
                String userHome = System.getProperty("user.home");
                File downloadsDir = new File(userHome, "Downloads");
                if (!downloadsDir.exists()) {
                    downloadsDir.mkdirs();
                }

                // 从URL中解析文件名
                String fileName = extractFileNameFromUrl(downloadUrl);
                if (StrUtil.isBlank(fileName)) {
                    fileName = "update.zip"; // 默认文件名
                }

                File downloadFile = new File(downloadsDir, fileName);

                // 如果文件已存在，询问用户是否覆盖
                if (downloadFile.exists()) {
                    int option = JOptionPane.showConfirmDialog(
                            parent,
                            "文件 " + fileName + " 已存在于Downloads文件夹中。\n是否要覆盖它？",
                            "文件已存在",
                            JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE
                    );
                    if (option != JOptionPane.YES_OPTION) {
                        callback.onComplete(false, null, "用户取消了下载");
                        return;
                    }
                }

                // 创建文件
                raf = new RandomAccessFile(downloadFile, "rw");

                // 打开HTTP连接
                URL url = new URL(downloadUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(10000); // 10秒连接超时
                connection.setReadTimeout(10000); // 10秒读取超时

                // 获取文件大小
                long fileLength = connection.getContentLengthLong();

                // 显示进度对话框
                ProgressMonitor monitor = new ProgressMonitor(
                        parent,
                        "正在下载更新...",
                        "开始下载...",
                        0,
                        100
                );
                monitor.setMillisToDecideToPopup(0); // 立即显示
                monitor.setMillisToPopup(0); // 立即显示

                // 用于标记是否取消下载
                AtomicBoolean cancelled = new AtomicBoolean(false);

                // 获取输入流
                in = connection.getInputStream();

                // 缓冲区
                byte[] buffer = new byte[8192];
                long totalBytesRead = 0;
                int bytesRead;

                // 读取数据并写入文件
                while ((bytesRead = in.read(buffer)) != -1 && !cancelled.get()) {
                    // 检查是否取消
                    if (monitor.isCanceled()) {
                        cancelled.set(true);
                        raf.close();
                        break;
                    }

                    // 写入文件
                    raf.write(buffer, 0, bytesRead);
                    totalBytesRead += bytesRead;

                    // 更新进度
                    if (fileLength > 0) {
                        int progress = (int) ((totalBytesRead * 100) / fileLength);
                        monitor.setProgress(progress);
                        monitor.setNote("已下载: " + formatBytes(totalBytesRead) + " / " + formatBytes(fileLength));
                    } else {
                        monitor.setNote("已下载: " + formatBytes(totalBytesRead));
                    }
                }

                // 检查是否取消
                if (cancelled.get() || monitor.isCanceled()) {
                    // 用户取消了下载
                    FileUtil.del(downloadFile); // 删除未完成的文件
                    callback.onComplete(false, null, "用户取消了下载");
                } else {
                    // 下载完成
                    callback.onComplete(true, downloadFile, null);
                }

            } catch (Exception e) {
                log.error("下载更新时发生错误", e);
                callback.onComplete(false, null, "下载失败: " + e.getMessage());
            } finally {
                // 关闭资源
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        log.warn("关闭输入流时发生错误", e);
                    }
                }
                if (raf != null) {
                    try {
                        raf.close();
                    } catch (IOException e) {
                        log.warn("关闭文件时发生错误", e);
                    }
                }
            }
        }).start();
    }
    
    /**
     * 从URL中提取文件名
     * @param url URL
     * @return 文件名
     */
    private static String extractFileNameFromUrl(String url) {
        if (StrUtil.isBlank(url)) {
            return null;
        }
        
        // 从URL的路径部分获取文件名
        try {
            java.net.URI uri = new java.net.URI(url);
            String path = uri.getPath();
            if (StrUtil.isNotBlank(path)) {
                int lastSlashIndex = path.lastIndexOf('/');
                if (lastSlashIndex >= 0 && lastSlashIndex < path.length() - 1) {
                    return path.substring(lastSlashIndex + 1);
                }
            }
        } catch (Exception e) {
            log.warn("解析URL时发生错误", e);
        }
        
        // 如果无法从路径获取，则尝试从查询参数获取
        int lastSlashIndex = url.lastIndexOf('/');
        if (lastSlashIndex >= 0 && lastSlashIndex < url.length() - 1) {
            String part = url.substring(lastSlashIndex + 1);
            int queryIndex = part.indexOf('?');
            if (queryIndex > 0) {
                return part.substring(0, queryIndex);
            } else {
                return part;
            }
        }
        
        return null;
    }
    
    /**
     * 格式化字节数
     * @param bytes 字节数
     * @return 格式化后的字符串
     */
    private static String formatBytes(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        } else if (bytes < 1024 * 1024) {
            return String.format("%.2f KB", bytes / 1024.0);
        } else if (bytes < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", bytes / (1024.0 * 1024));
        } else {
            return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
        }
    }
    
    /**
     * 下载完成回调接口
     */
    public interface DownloadCallback {
        /**
         * 当下载完成时调用
         * @param success 是否成功
         * @param file 下载的文件，如果失败则为null
         * @param errorMsg 错误信息，如果成功则为null
         */
        void onComplete(boolean success, File file, String errorMsg);
    }
}